package org.anachronos.jeep.probe.test;

import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.Map;
import java.util.logging.Logger;

import org.anachronos.jeep.probe.Arg;
import org.anachronos.jeep.probe.OnMethod;
import org.anachronos.jeep.probe.OnMethod.Kind;
import org.anachronos.jeep.probe.Probe;
import org.anachronos.jeep.probe.ReturnArg;
import org.anachronos.jeep.probe.This;

import com.google.common.collect.MapMaker;

@Probe
public class JdbcExecutionTrace {
	private static final Logger logger = Logger.getLogger(JdbcExecutionTrace.class.getName()); 
	private static final Map<PreparedStatement, String> PREPARED_STATEMENT_MAP = 
		new MapMaker().weakKeys().makeMap();

	
	@OnMethod(kind=Kind.ENTRY,
			interfaceName="java/sql/Connection",
			methodName="prepare(Call|Statement)?",
			methodDescriptior=".*")
	public static void onPrepare(@ReturnArg PreparedStatement result, @Arg(0) String sqlStatement) {
		PREPARED_STATEMENT_MAP.put(result, sqlStatement);
	}

	@OnMethod(kind=Kind.ENTRY,
			interfaceName="java/sql/Statement",
			methodName="execute(Query|Update)?")
	public static void onStartExecuteStatement(@Arg(0) String sql) {
		logger.info("Start execute of:" + sql);
	}

	@OnMethod(kind=Kind.EXIT,
			interfaceName="java/sql/Statement",
			methodName="execute(Query|Update)?")
	public static void onFinishExecuteStatement(@Arg(0) String sql) {
		logger.info("Finish execute of:" + sql);
	}
	
	@OnMethod(kind=Kind.ENTRY,
			interfaceName="java/sql/PreparedStatement",
			methodName="execute",
			methodDescriptior="()Ljava/sql/PreparedStatement")
	public static void onStartExecutePreparedStatement(@This Statement statement) {
		logger.info("Start execute of:" + PREPARED_STATEMENT_MAP.get(statement));
	}

	@OnMethod(kind=Kind.EXIT,
			interfaceName="java/sql/PreparedStatement",
			methodName="execute")
	public static void onFinishExecutePreparedStatement(@This Statement statement) {
		logger.info("Finish execute of:" + PREPARED_STATEMENT_MAP.get(statement));
	}
}
